<!DOCTYPE html>
<html>
	<head>
		<title>testing dojo/_base/query</title>
		<style type="text/css">
			@import "../../resources/dojo.css";
		</style>
		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
		<script type="text/javascript">
			require(["dojo", "doh", "dojo/io/iframe", "dojo/domReady!"], function(dojo, doh){
				function createDocument(xml){
					var fauxXhr = { responseText: xml };
					if("DOMParser" in dojo.global){
						var parser = new DOMParser();
						fauxXhr.responseXML = parser.parseFromString(xml, "text/xml");
					}
					// kludge: use dojo.xhr contentHandler for XML to process IE XMLDOC as needed
					return dojo._contentHandlers["xml"](fauxXhr); // DOMDocument
				}

				// Legacy tests for dojo/_base/query.  Replaced by dojo/tests/query/query.html.
				// TODO: remove in 2.0.
				doh.register("t", 
					[
						// basic sanity checks
						"doh.is(4, (dojo.query('h3')).length);",
						"doh.is(1, (dojo.query('h1:first-child')).length);",
						"doh.is(2, (dojo.query('h3:first-child')).length);",
						"doh.is(1, (dojo.query('#t')).length);",
						//"doh.is(1, (dojo.query('#bug')).length);",
						"doh.is(4, (dojo.query('#t h3')).length);",
						"doh.is(1, (dojo.query('div#t')).length);",
						"doh.is(4, (dojo.query('div#t h3')).length);",
						"doh.is(0, (dojo.query('span#t')).length);",
						"doh.is(0, (dojo.query('.bogus')).length);",
						"doh.is(0, (dojo.query('.bogus', dojo.byId('container'))).length);",
						"doh.is(0, (dojo.query('#bogus')).length);",
						"doh.is(0, (dojo.query('#bogus', dojo.byId('container'))).length);",
						"doh.is(1, (dojo.query('#t div > h3')).length);",
						"doh.is(2, (dojo.query('.foo')).length);",
						"doh.is(1, (dojo.query('.foo.bar')).length);",
						"doh.is(2, (dojo.query('.baz')).length);",
						"doh.is(3, (dojo.query('#t > h3')).length);",

						"doh.is(2, (dojo.query('#baz,#foo,#t')).length);",

						"doh.is(1, dojo.query('.fooBar').length);",

						// syntactic equivalents
						"doh.is(12, (dojo.query('#t > *')).length);",
						"doh.is(12, (dojo.query('#t >')).length);",
						"doh.is(3, (dojo.query('.foo >')).length);",
						"doh.is(3, (dojo.query('.foo > *')).length);",

						// with a root, by ID
						"doh.is(3, (dojo.query('> *', 'container')).length);",
						"doh.is(3, (dojo.query('> h3', 't')).length);",

						// compound queries
						"doh.is(2, (dojo.query('.foo, .bar')).length);",
						"doh.is(2, (dojo.query('.foo,.bar')).length);",

						// multiple class attribute
						"doh.is(1, (dojo.query('.foo.bar')).length);",
						"doh.is(2, (dojo.query('.foo')).length);",
						"doh.is(2, (dojo.query('.baz')).length);",

						// case sensitivity
						"doh.is(1, (dojo.query('span.baz')).length);",
						"doh.is(1, (dojo.query('sPaN.baz')).length);",
						"doh.is(1, (dojo.query('SPAN.baz')).length);",
						"doh.is(1, (dojo.query('[class = \"foo bar\"]')).length);",
						"doh.is(2, (dojo.query('[foo~=\"bar\"]')).length);",
						"doh.is(2, (dojo.query('[ foo ~= \"bar\" ]')).length);",

						// "t.is(0, (dojo.query('[ foo ~= \"\\'bar\\'\" ]')).length);",
						"doh.is(3, (dojo.query('[foo]')).length);",
						"doh.is(1, (dojo.query('[foo$=\"thud\"]')).length);",
						"doh.is(1, (dojo.query('[foo$=thud]')).length);",
						"doh.is(1, (dojo.query('[foo$=\"thudish\"]')).length);",
						"doh.is(1, (dojo.query('[id$=\\'55555\\']')).length);",
						"doh.is(1, (dojo.query('#t [foo$=thud]')).length);",
						"doh.is(1, (dojo.query('#t [ title $= thud ]')).length);",
						"doh.is(0, (dojo.query('#t span[ title $= thud ]')).length);",
						"doh.is(2, (dojo.query('[foo|=\"bar\"]')).length);",
						"doh.is(1, (dojo.query('[foo|=\"bar-baz\"]')).length);",
						"doh.is(0, (dojo.query('[foo|=\"baz\"]')).length);",
						"doh.is(dojo.byId('_foo'), dojo.query('.foo:nth-child(2)')[0]);",
						"doh.is(dojo.query('style')[0], dojo.query(':nth-child(2)')[0]);",

						// descendant selectors
						"doh.is(3, dojo.query('>', 'container').length);",
						"doh.is(0, dojo.query('> .not-there').length);",
						"doh.is(3, dojo.query('> *', 'container').length);",
						"doh.is(2, dojo.query('> [qux]', 'container').length);",
						"doh.is('child1', dojo.query('> [qux]', 'container')[0].id);",
						"doh.is('child3', dojo.query('> [qux]', 'container')[1].id);",
						"doh.is(3, dojo.query('>', 'container').length);",
						"doh.is(3, dojo.query('> *', 'container').length);",
						"doh.is(3, dojo.query('>*', 'container').length);",
						"doh.is('passed', dojo.query('#bug')[0].value);",

						// bug 9071
						"doh.is(2, (dojo.query('a', 't4')).length);",
						"doh.is(2, (dojo.query('p a', 't4')).length);",
						"doh.is(2, (dojo.query('div p', 't4')).length);",
						"doh.is(2, (dojo.query('div p a', 't4')).length);",
						"doh.is(2, (dojo.query('.subA', 't4')).length);",
						"doh.is(2, (dojo.query('.subP .subA', 't4')).length);",
						"doh.is(2, (dojo.query('.subDiv .subP', 't4')).length);",
						"doh.is(2, (dojo.query('.subDiv .subP .subA', 't4')).length);",


						// failed scope arg
						"doh.is(0, (dojo.query('*', 'thinger')).length);",
						"doh.is(0, (dojo.query('div#foo').length));",

						// sibling selectors
						"doh.is(1, dojo.query('+', 'container').length);",
						"doh.is(3, dojo.query('~', 'container').length);",
						"doh.is(1, (dojo.query('.foo+ span')).length);",
						"doh.is(1, (dojo.query('.foo+span')).length);",
						"doh.is(1, (dojo.query('.foo +span')).length);",
						"doh.is(1, (dojo.query('.foo + span')).length);",
						"doh.is(4, (dojo.query('.foo~ span')).length);",
						"doh.is(4, (dojo.query('.foo~span')).length);",
						"doh.is(4, (dojo.query('.foo ~span')).length);",
						"doh.is(4, (dojo.query('.foo ~ span')).length);",
						"doh.is(1, (dojo.query('#foo~ *')).length);",
						"doh.is(1, (dojo.query('#foo ~*')).length);",
						"doh.is(1, (dojo.query('#foo ~*')).length);",
						"doh.is(1, (dojo.query('#foo ~ *')).length);",
						"doh.is(1, (dojo.query('#foo ~')).length);",
						"doh.is(1, (dojo.query('#foo~')).length);",

						// sub-selector parsing
						"doh.is(1, dojo.query('#t span.foo:not(span:first-child)').length);",
						"doh.is(1, dojo.query('#t span.foo:not(:first-child)').length);",

						// nth-child tests
						"doh.is(2, dojo.query('#t > h3:nth-child(odd)').length);",
						"doh.is(3, dojo.query('#t h3:nth-child(odd)').length);",
						"doh.is(3, dojo.query('#t h3:nth-child(2n+1)').length);",
						"doh.is(1, dojo.query('#t h3:nth-child(even)').length);",
						"doh.is(1, dojo.query('#t h3:nth-child(2n)').length);",
						"doh.is(1, dojo.query('#t h3:nth-child(2n+3)').length);",
						"doh.is(2, dojo.query('#t h3:nth-child(1)').length);",
						"doh.is(1, dojo.query('#t > h3:nth-child(1)').length);",
						"doh.is(3, dojo.query('#t :nth-child(3)').length);",
						"doh.is(0, dojo.query('#t > div:nth-child(1)').length);",
						"doh.is(7, dojo.query('#t span').length);",
						"doh.is(3, dojo.query('#t > *:nth-child(n+10)').length);",
						"doh.is(1, dojo.query('#t > *:nth-child(n+12)').length);",
						"doh.is(10, dojo.query('#t > *:nth-child(-n+10)').length);",
						"doh.is(5, dojo.query('#t > *:nth-child(-2n+10)').length);",
						"doh.is(6, dojo.query('#t > *:nth-child(2n+2)').length);",
						"doh.is(5, dojo.query('#t > *:nth-child(2n+4)').length);",
						"doh.is(5, dojo.query('#t > *:nth-child(2n+4)').length);",
						"doh.is(5, dojo.query('#t> *:nth-child(2n+4)').length);",
						"doh.is(12, dojo.query('#t > *:nth-child(n-5)').length);",
						"doh.is(12, dojo.query('#t >*:nth-child(n-5)').length);",
						"doh.is(6, dojo.query('#t > *:nth-child(2n-5)').length);",
						"doh.is(6, dojo.query('#t>*:nth-child(2n-5)').length);",
						
						// :checked pseudo-selector
						"doh.is(2, dojo.query('#t2 > :checked').length);",
						"doh.is(dojo.byId('checkbox2'), dojo.query('#t2 > input[type=checkbox]:checked')[0]);",
						"doh.is(dojo.byId('radio2'), dojo.query('#t2 > input[type=radio]:checked')[0]);",
						"doh.is(2, dojo.query('#t2select option:checked').length);",
						
						// special characters in attribute values
						function attrSpecialChars(){
							// bug 10651
							doh.is(1, dojo.query('option[value=a+b]', 'attrSpecialChars').length, "value=a+b");
							doh.is(1, dojo.query('option[value=a~b]', 'attrSpecialChars').length, "value=a~b");
							doh.is(1, dojo.query('option[value=a^b]', 'attrSpecialChars').length, "value=a^b");
							doh.is(1, dojo.query('option[value=\"a+b\"]', 'attrSpecialChars').length, "value=\"a^b\"");
							doh.is(1, dojo.query('option[value=\"a~b\"]', 'attrSpecialChars').length, "value=\"a~b\"");
							doh.is(1, dojo.query('option[value=\"a^b\"]', 'attrSpecialChars').length, "value=\"a^b\"");

							// selector with substring that contains equals sign (bug 7479)
							doh.is(1, dojo.query("a[href*='foo=bar']", 'attrSpecialChars').length, "a[href*='foo=bar']");

							// selector with substring that contains brackets (bug 9193, 11189, 13084)
							// note: inner quotes don't work in second dojo.query(), not sure why
							doh.is(1, dojo.query('input[name="data[foo][bar]"]', 'attrSpecialChars').length, "data[foo][bar]");
							doh.is(1, dojo.query('input[name=data\\[foo\\]\\[bar\\]]', 'attrSpecialChars').length, "data\\[foo\\]\\[bar\\]");
							doh.is(1, dojo.query('input[name="foo\\[0\\].bar"]', 'attrSpecialChars').length, "foo[0].bar");
							doh.is(1, dojo.query('input[name="test[0]"]', 'attrSpecialChars').length, "test[0]");
						},

						// check for correct document order
						function domOrder() {
							var inputs = dojo.query(".upperclass .lowerclass input");
							doh.is("notbug", inputs[0].id);
							doh.is("bug", inputs[1].id);
							doh.is("checkbox1", inputs[2].id);
							doh.is("checkbox2", inputs[3].id);
							doh.is("radio1", inputs[4].id);
							doh.is("radio2", inputs[5].id);
							doh.is("radio3", inputs[6].id);
						},

						// cross-document queries
						{

							name: "crossDocumentQuery",
							setUp: function(){
								this.t3 = window.frames["t3"];
								this.doc = dojo.io.iframe.doc(t3);
								this.doc.open();
								this.doc.write([
									"<html><head>",
									"<title>inner document</title>",
									"</head>",
									"<body>",
									"<div id='st1'><h3>h3 <span>span <span> inner <span>inner-inner</span></span></span> endh3 </h3></div>",
									"</body>",
									"</html>"
								].join(""));
							},
							runTest: function(){
								doh.is(1, dojo.query('h3', dojo.byId("st1", this.doc)).length);
								// use a long query to force a test of the XPath system on FF. see bug #7075
								doh.is(1, dojo.query('h3 > span > span > span', dojo.byId("st1", this.doc)).length);
								doh.is(1, dojo.query('h3 > span > span > span', this.doc.body.firstChild).length);
							}
						},

						// :empty pseudo-selector
						"doh.is(4, dojo.query('#t > span:empty').length);",
						"doh.is(6, dojo.query('#t span:empty').length);",
						"doh.is(0, dojo.query('h3 span:empty').length);",
						"doh.is(1, dojo.query('h3 :not(:empty)').length);",

						// escaping of ":" chars inside an ID
						function silly_IDs1(){
							doh.t(document.getElementById("silly:id::with:colons"));
							doh.is(1, dojo.query("#silly\\:id\\:\\:with\\:colons").length);
						},
						function NodeList_identity(){
							var foo = new dojo.NodeList([dojo.byId("container")]);
							doh.is(foo, dojo.query(foo));
						},
						function xml(){
							var doc = createDocument([
								"<ResultSet>",
									"<Result>One</Result>",
									"<RESULT>Two</RESULT>",
									"<result>Three</result>",
									"<result>Four</result>",
								"</ResultSet>"
							].join("")
							);
							var de = doc.documentElement;

							doh.is(2, dojo.query("result", de).length, "all lower");
							doh.is(1, dojo.query("Result", de).length, "mixed case");
							doh.is(1, dojo.query("RESULT", de).length, "all upper");
							doh.is(0, dojo.query("resulT", de).length, "no match");
							doh.is(0, dojo.query("rEsulT", de).length, "no match");
						},
						function xml_attrs(){
							var doc = createDocument([
								"<ResultSet>",
									"<RESULT thinger='blah'>ONE</RESULT>",
									"<RESULT thinger='gadzooks'><CHILD>Two</CHILD></RESULT>",
								"</ResultSet>"
							].join(""));
							var de = doc.documentElement;

							doh.is(2, dojo.query("RESULT", de).length, "result elements");
							doh.is(0, dojo.query("RESULT[THINGER]", de).length, "result elements with attrs (wrong)");
							doh.is(2, dojo.query("RESULT[thinger]", de).length, "result elements with attrs");
							doh.is(1, dojo.query("RESULT[thinger=blah]", de).length, "result elements with attr value");
							doh.is(1, dojo.query("RESULT > CHILD", de).length, "Using child operator");
						},
						function sort(){
							var i = dojo.query("div");
							// smoke test
							i.sort(function(a,b){ return 1; })
						}
					]
				);
				doh.runOnLoad();
			});
		</script>
	</head>
	<body class="upperclass">
		<h1>Back-compat tests for dojo.query()</h1>
		<div id="t" class="lowerclass">
			<h3>h3 <span>span</span> endh3 </h3>
			<!-- comment to throw things off -->
			<div class="foo bar" id="_foo">
				<h3>h3</h3>
				<span id="foo"></span>
				<span></span>
			</div>
			<h3>h3</h3>
			<h3 class="baz foobar" title="thud">h3</h3>
			<span class="fooBar baz foo"></span>
			<span foo="bar"></span>
			<span foo="baz bar thud"></span>
			<!-- FIXME: should foo="bar-baz-thud" match? [foo$=thud] ??? -->
			<span foo="bar-baz-thudish" id="silly:id::with:colons"></span>
			<div id="container">
				<div id="child1" qux="true"></div>
				<div id="child2"></div>
				<div id="child3" qux="true"></div>
			</div>
			<div qux="true"></div>
			<input id="notbug" name="bug" type="hidden" value="failed"> 
			<input id="bug" type="hidden" value="passed"> 
		</div>
		<div id="t2" class="lowerclass">
			<input type="checkbox" name="checkbox1" id="checkbox1" value="foo">
			<input type="checkbox" name="checkbox2" id="checkbox2" value="bar" checked>

			<input type="radio" name="radio" id="radio1" value="thinger">
			<input type="radio" name="radio" id="radio2" value="stuff" checked>
			<input type="radio" name="radio" id="radio3" value="blah">
		</div>
		<select id="t2select" multiple="multiple">
			<option>0</option>
			<option selected="selected">1</option>
			<option selected="selected">2</option>
		</select>
		
		<iframe id="t3" name="t3" src="../../resources/blank.html"></iframe>
		<div id="t4">
			<div id="one" class="subDiv">
				<p class="one subP"><a class="subA">one</a></p>
				<div id="two" class="subDiv">
					<p class="two subP"><a class="subA">two</a></p>
				</div>
			</div>
		</div>
		<div id='other'>
		  <div id='abc55555'></div>
		  <div id='abd55555efg'></div>
		  <div id='55555abc'></div>
		  <div id='1'></div>
		  <div id='2c'></div>
		  <div id='3ch'></div>
		  <div id='4chr'></div>
		  <div id='5char'></div>
		  <div id='6chars'></div>
		</div>
		
		<div id="attrSpecialChars">
			<select name="special">
				<!-- tests for special characters in attribute values (characters that are part of query syntax) -->
				<option value="a+b">1</option>
				<option value="a~b">2</option>
				<option value="a^b">3</option>
			</select>

			<!-- tests for quotes in attribute values -->
			<a href="foo=bar">hi</a>
			<!-- tests for brackets in attribute values -->
			<input name="data[foo][bar]">
			<!-- attribute name with a dot, goes down separate code path -->
			<input name="foo[0].bar">
			<input name="test[0]">
		</div>
	</body>
</html>

